// /////////////////////////////////////////////////////////////////////////////
//
// Name:            ScriptManager.cpp
// Author:          Michael Bartsch
//
// Desc:            The Script Manager is the central interface point to all
//                  script related functions of this program.
//
// License:         Copyright (C) 2008-2009 Michael Bartsch
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the GNU General Public
//                  License as published by the Free Software Foundation,
//                  either version 3 of the License, or (at your option) any
//                  later version.
//
//                  This program is distributed in the hope that it will be
//                  useful, but WITHOUT ANY WARRANTY; without even the implied
//                  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//                  PURPOSE. See the GNU General Public License for more
//                  details.
//
//                  You should have received a copy of the GNU General Public
//                  License along with this program. If not, see
//                  <http://www.gnu.org/licenses/>.
//
// /////////////////////////////////////////////////////////////////////////////

// Include required header file(s).
#include "ScriptManager.h"

// Glue functions:  (Base)
// Overrides the print function of Lua.
/**
  *  Overrides the print function of Lua so that it prints its output to the
  *  Script Manager.
  *
  *  @see CScriptManager::setOutput
  */
int lua_altPrint(lua_State *L)
{
    int n = lua_gettop(L);  /* number of arguments */
    lua_getglobal(L, "tostring");
    std::string output;

    for (int i = 1; i <= n; i++)
    {
       const char *s = NULL;
       lua_pushvalue(L, -1);  /* function to be called */
       lua_pushvalue(L, i);   /* value to print */
       lua_call(L, 1, 1);

       s = lua_tostring(L, -1);  /* get result */

       if(s == NULL)
        return luaL_error(L, LUA_QL("tostring") " must return a string to "
                           LUA_QL("print"));

       if (i>1) output.append("\t");
       output.append(s);
       lua_pop(L, 1);  /* pop result */
    }

    output.append("\n");
    CScriptManager::Instance()->setOutput(output);
    return 0;
}


// Constructor of the CScriptManager class.
CScriptManager::CScriptManager()
: luaState(NULL)
{
}

// Deconstructor of the CScriptManager class.
CScriptManager::~CScriptManager()
{
    clear();
}

// CScriptManager singleton.
CScriptManager* CScriptManager::pInstance = 0;

CScriptManager* CScriptManager::Instance()
{
	if(pInstance == 0)
	  pInstance = new CScriptManager;

	return pInstance;
}

// Initialise the Script Manager.
void CScriptManager::init()
{
    // Init Lua.
    luaState = luaL_newstate();

    // Open Lua's base libraries.
    luaopen_base(luaState);
    luaopen_string(luaState);
    luaopen_math(luaState);
    luaopen_debug(luaState);

    // Register custom functions.
    lua_register(luaState, "print", lua_altPrint);

    registerColourAnalyser(luaState);
    registerCommunicator(luaState);
    registerAI(luaState);
}

// Deinitialise the Script Manager.
void CScriptManager::clear()
{
    if(luaState != NULL)
    {
       lua_close(luaState);
       luaState = NULL;
    }
}

// Executes the given string.
void CScriptManager::executeString(const char* string)
{
    outputString = "";
    int error = luaL_dostring(luaState, string);

    if(error)
    {
       outputString = lua_tostring(luaState, -1);
       outputString.append("\n");

       lua_pop(luaState, 1);
    }
}

// Executes the given file.
void CScriptManager::executeFile(const char* filename)
{
    outputString = "";
    int error = luaL_dofile(luaState, filename);

    if(error)
    {
       outputString = lua_tostring(luaState, -1);
       outputString.append("\n");

       lua_pop(luaState, 1);
    }
}

// Sets the output string.
// Note: For use by external classes and functions.
void CScriptManager::setOutput(std::string output)
{
    outputString = output;
}

// Retrieves the output string.
std::string CScriptManager::getOutput()
{
    return outputString;
}
// End of File.
